#!/usr/bin/env ruby
#
# Generates abbreviations for cities
#

$states2abbrevs = nil

def get_abbreviation(state)
  if !$states2abbrevs
    $states2abbrevs = { 
      'ALABAMA' => 'AL',
      'Alaska' => 'AK',
      'American Samoa' => 'AS',
      'Arizona' => 'AZ',
      'Arkansas' => 'AR',
      'California' => 'CA',
      'Colorado' => 'CO',
      'Connecticut' => 'CT',
      'Delaware' => 'DE',
      'District Of Columbia' => 'DC',
      'Federated States Of Micronesia' => 'FM',
      'Florida' => 'FL',
      'Georgia' => 'GA',
      'Guam' => 'GU',
      'Hawaii' => 'HI',
      'Idaho' => 'ID',
      'Illinois' => 'IL',
      'Indiana' => 'IN',
      'Iowa' => 'IA',
      'Kansas' => 'KS',
      'Kentucky' => 'KY',
      'Louisiana' => 'LA',
      'Maine' => 'ME',
      'Marshall Islands' => 'MH',
      'Maryland' => 'MD',
      'Massachusetts' => 'MA',
      'Michigan' => 'MI',
      'Minnesota' => 'MN',
      'Mississippi' => 'MS',
      'Missouri' => 'MO',
      'Montana' => 'MT',
      'Nebraska' => 'NE',
      'Nevada' => 'NV',
      'New Hampshire' => 'NH',
      'New Jersey' => 'NJ',
      'New Mexico' => 'NM',
      'New York' => 'NY',
      'North Carolina' => 'NC',
      'North Dakota' => 'ND',
      'Northern Mariana Islands' => 'MP',
      'Ohio' => 'OH',
      'Oklahoma' => 'OK',
      'Oregon' => 'OR',
      'Palau' => 'PW',
      'Pennsylvania' => 'PA',
      'Puerto Rico' => 'PR',
      'Rhode Island' => 'RI',
      'South Carolina' => 'SC',
      'South Dakota' => 'SD',
      'Tennessee' => 'TN',
      'Texas' => 'TX',
      'Utah' => 'UT',
      'Vermont' => 'VT',
      'Virgin Islands' => 'VI',
      'Virginia' => 'VA',
      'Washington' => 'WA',
      'West Virginia' => 'WV',
      'Wisconsin' => 'WI',
      'Wyoming' => 'WY'
    }
  end
  return $states2abbrevs[state]
end

def main(argv)

  def log(s)
    STDERR.puts s
  end

  def save_city(city,state,cities2statess)
    states = cities2statess[city]
    if !states
      states = []
      cities2statess[city] = states
    end
    states << state
  end

  def gen_abbreviation_throwing(city,state,states2cities2abbrevs,use_abbreviation)
    dir = city.downcase
    if use_abbreviation
      log state
      abbrev = get_abbreviation state
      return if !abbrev
      dir += abbrev
    end
    log city + ', ' + state + ' -> ' + dir
    Dir.mkdir dir if !File.exists? dir
    File.open File.join(dir,'index.php'), 'w' do |out|
      out.write '<?php header("Location: http://maatings.org/' + state + '/' + city + '/"); exit(0); ?>'
    end
    cities2abbrevs = states2cities2abbrevs[state]
    if !cities2abbrevs
      cities2abbrevs = {}
      states2cities2abbrevs[state] = cities2abbrevs
    end
    cities2abbrevs[city] = dir
  end

  def gen_abbreviation(city,state,states2cities2abbrevs,use_abbreviation)
    begin
      gen_abbreviation_throwing city,state,states2cities2abbrevs,use_abbreviation
    rescue Exception => e
      log 'ERROR: ' + e
    end
  end 

  # Maps cities to list of states
  cities2statess = {}

  # Maps states to cities to abbreviations
  states2cities2abbrevs = {}
  
  # Find all the cities
  Dir[File.join('**','data.xml')].each do |data_xml|
    city  = File.basename(File.dirname(data_xml))
    state = File.basename(File.dirname(File.dirname(data_xml)))
    next if !state or state == '.' or state == '..'
    save_city city,state,cities2statess
  end

  # Generate an abbreviation for every city/state pair
  cities2statess.each do |city,states|
    if states.length == 1
      gen_abbreviation city,states[0],states2cities2abbrevs,false
    else
      states.each do |state|
        gen_abbreviation city,state,states2cities2abbrevs,true
      end
    end
  end

  # Generate the abbrev/index.php
  Dir.mkdir 'abbrev' if !File.exists? 'abbrev'
  File.open 'abbrev/index.php','w' do |out|
    out.puts "<?php"
    out.puts " define('BASE','../');"
    out.puts " define('TITLE', 'Abbreviations');"
    out.puts " define('SMALL_CONTENT',TRUE);"
    out.puts " include BASE . 'menu_head.php';"
    out.puts "?>"
    states = []
    states2cities2abbrevs.keys.each do |key|
      states << key.to_s if key.class == String
    end
    states.sort!
    states.each do |state|
      next if !state
      state = state.to_s
      cities2abbrevs = states2cities2abbrevs[state]
      next if !cities2abbrevs
      out.puts '<a name="_' + state + '"></a>';
      out.puts '<div class="tableTitle"><span class="tableTitleLeft">' + state + '</span><span class="tableTitleRight"> '+ '<a href="#top">'+ 'top'+ '</a>'+ '</span>' + '</div>'
      out.puts '<table>'
      cities = []
      cities2abbrevs.keys do |key|
        cities << key.to_s
      end
      cities.sort!
      cities.each do |city|
        city = city.to_s
        # XXXXXXX
        # Throwing this for some reason
        # ./script/gen_abbreviations:153: warning: multiple values for a block parameter (2 for 1)
        #   from ./script/gen_abbreviations:153
        #
        abbrev = cities2abbrevs[city]
        abbrev = abbrev.to_s
        out.puts '<tr>'
        link = state + '/' + city
        out.puts '<td><a href="' + link + '">' + city + '</a></td>'
        out.puts '<td>&rarr;</td>'
        out.puts '<td><a href="' + link + '">' + abbrev + '</a></td>'
        out.puts '</tr>'
        out.puts '</table>'
      end
    end
    out.puts "<?php"
    out.puts " include BASE . 'menu_foot.php';"
    out.puts "?>"
  end
  
end

main ARGV


